﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using VideoLink.Frames;

namespace VideoLink.Streams
{
    /// <summary>
    /// Базовый для всех компонентов источников видео класс.
    /// Предоставляет базовые функции для управления воспроизведением
    /// и получения данных для пересылки.
    /// </summary>
    public partial class VideoSourceBase : UserControl, IDisposable
    {
        #region Private and protected properties

        /// <summary>
        /// Текущее состояние процесса воспроизведения
        /// </summary>
        private PlaybackState state;

        /// <summary>
        /// Панель, которая предназначена для размещения компонентов
        /// или непосредственного отображения видео
        /// </summary>
        protected Panel ViewportPanel
        {
            get
            {
                return splitContainer.Panel2;
            }
        }
        
        /// <summary>
        /// Показывает, надо ли посылать данные при следующем вызове GetFrameData
        /// </summary>
        protected bool needSendData = true;

        #endregion

        #region Public properties

        /// <summary>
        /// Путь к файлу видео, который воспроизводится в данном потоке.
        /// Значение этого свойства отображается также в шапке контрола
        /// </summary>
        public virtual string FileName
        {
            get { return fileNameL.Text; }
            protected set { fileNameL.Text = value; }
        }

        /// <summary>
        /// ID потока. Уникален для каждого потока
        /// </summary>
        public int StreamID { get; private set; }

        /// <summary>
        /// Текущее состояние процесса воспроизведения
        /// </summary>
        public PlaybackState State
        {
            get { return state; }

            protected set
            {
                if (state == value)
                    return;

                switch (value)
                {
                    case PlaybackState.Play: OnPlay(this, EventArgs.Empty); break;
                    case PlaybackState.Pause: OnPause(this, EventArgs.Empty); break;
                    case PlaybackState.Stop: OnStop(this, EventArgs.Empty); break;
                }
                state = value;
            }
        }
        
        #endregion

        /// <summary>
        /// Создать экземпляр класса по умолчанию
        /// </summary>
        public VideoSourceBase()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Создать экземпляр класса с указанным ID потока
        /// </summary>
        /// <param name="streamID"></param>
        public VideoSourceBase(int streamID)
            : this()
        {
            StreamID = streamID;
        }

        /// <summary>
        /// Закрыть поток и освободить все ресурсы.
        /// После вызова экземпляр становится непригодным для использования.
        /// Данный метод необходимо вызывать, когда поток становится не нужным
        /// или должен быть прекращён.
        /// </summary>
        public virtual void Close()
        {
            
        }

        /// <summary>
        /// Вызывается, когда поток необходимо закрыть,
        /// в частности, когда нажата кнопка "Закрыть"
        /// </summary>
        public event EventHandler NeedClose;

        #region Playback

        /// <summary>
        /// Вызывается при изменении свойства State в значение Play
        /// или при нажатии кнопки "Play" на контроле.
        /// Выполняются все действия, связанные с запуском воспроизведения
        /// </summary>
        /// <param name="sender">-</param>
        /// <param name="e">-</param>
        protected virtual void OnPlay(object sender, EventArgs e)
        {
            state = PlaybackState.Play;
            needSendData = true;
        }

        /// <summary>
        /// Вызывается при изменении свойства State в значение Pause
        /// или при нажатии кнопки "Pause" на контроле.
        /// Выполняются все действия, связанные с приостановкой воспроизведения
        /// </summary>
        /// <param name="sender">-</param>
        /// <param name="e">-</param>
        protected virtual void OnPause(object sender, EventArgs e)
        {
            state = PlaybackState.Pause;
            needSendData = true;
        }

        /// <summary>
        /// Вызывается при изменении свойства State в значение Stop
        /// или при нажатии кнопки "Stop" на контроле.
        /// Выполняются все действия, связанные с остановкой воспроизведения
        /// </summary>
        /// <param name="sender">-</param>
        /// <param name="e">-</param>
        protected virtual void OnStop(object sender, EventArgs e)
        {
            state = PlaybackState.Stop;
            needSendData = true;
        }

        /// <summary>
        /// Получить данные, соответствующие данному кадру.
        /// </summary>
        /// <returns>Текущее состояние потока</returns>
        public virtual VideoStreamState GetFrameData()
        {
            throw new NotImplementedException();
        }
        
        #endregion

        /// <summary>
        /// Обработчик события клика по кнопке "Закрыть"
        /// </summary>
        /// <param name="sender">-</param>
        /// <param name="e">-</param>
        private void closeIB_Click(object sender, EventArgs e)
        {
            Close();
            if (NeedClose != null)
                NeedClose(this, EventArgs.Empty);
        }
    }
}
